package com.company.笔试.死锁;

import java.util.concurrent.Callable;

public class DeadLock {
	
	public static void main(String[] args) {
		DeadLockThread deadLock1=new DeadLockThread(true);
		DeadLockThread deadLock2=new DeadLockThread(false);
		Thread t1=new Thread(deadLock1);
		Thread t2=new Thread(deadLock2);
		t1.start();
		t2.start();
	}
	
}
 
class DeadLockThread implements Runnable{
	boolean flag;
	static Object o1=new Object();//这里必须是静态变量，否则加锁就不是在同一个对象上加锁了
	static Object o2=new Object();	
	
	public DeadLockThread(boolean flag){
		this.flag=flag;
	}
 
	public void run() {
		if(flag){
			synchronized(o1){
				try{
					Thread.sleep(10);
					System.out.println("lock! o1");
				}
				catch(InterruptedException e){
					e.printStackTrace();
				}
				synchronized(o2){//要放在o1临界区内，因为要保持o1的锁，申请o2的锁
					System.out.println("I am not dead lock!");
				}
			}			
		}
		else{
			synchronized(o2){
				try{
					Thread.sleep(10);
					System.out.println("lock! o2");
				}
				catch(InterruptedException e){
					e.printStackTrace();
				}
				synchronized(o1){//此处类似，保持o2的锁，申请o1的锁
					System.out.println("I am not dead lock, too.");
				}
			}			
		}
	}
	
}

class myDeadLine1 extends Thread{
	public static  Recourse aa=new Recourse(1);
	public static  Recourse bb=new Recourse(1);
	public myDeadLine1(String name) {
		super(name);
	}

	@Override
	public void run() {
		synchronized(aa){
			System.out.println("我获得了aa");
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			synchronized (bb){
				System.out.println("我获得了bb");
			}

		}
	}

	public static void main(String[] args) {
		myDeadLine1 line1 = new myDeadLine1("line1");
		line1.start();
		synchronized(bb){
			System.out.println("我获得了bb");
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			synchronized (aa){
				System.out.println("我获得了aa");
			}
		}
	}
}

class myDeadLine2 implements Runnable{
	public static  Recourse aa=new Recourse(1);
	public static  Recourse bb=new Recourse(1);


	@Override
	public void run() {
		synchronized(aa){
			System.out.println("我获得了aa");
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			synchronized (bb){
				System.out.println("我获得了bb");
			}

		}
	}

	public static void main(String[] args) {
		myDeadLine2 line2 = new myDeadLine2();
		new Thread(line2).start();

		synchronized(bb){
			System.out.println("我获得了bb");
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			synchronized (aa){
				System.out.println("我获得了aa");
			}
		}
	}
}

class myDeadLine3 implements Callable{

	@Override
	public Object call() throws Exception {
		return null;
	}
}


class Recourse{
	public int value;

	public Recourse(int value) {
		this.value = value;
	}
}